﻿namespace FileWatcher
{
    using System;
    using System.IO;
    using System.Reactive.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            FileSystemWatcherSample();
        }

        static void FileSystemWatcherSample()
        {
            Console.WriteLine("#FileSystemWatcherSample");
            var watcher = new FileSystemWatcher();
            // ドキュメントフォルダのテキストを監視
            watcher.Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            watcher.Filter = "*.txt";
            watcher.NotifyFilter = NotifyFilters.LastAccess |
                NotifyFilters.LastWrite |
                NotifyFilters.FileName;

            watcher.ChangedAsObservable()
                // フィルタリングする前の変更
                .Do(e => Console.WriteLine("Changed"))
                // 1秒イベントが発生しないのを待つ
                .Throttle(TimeSpan.FromSeconds(1))
                // 購読
                .Subscribe(e => Console.WriteLine(
                    "{0:yyyy/MM/dd HH:mm:ss.fff} {1} {2}", 
                    DateTime.Now,
                    e.ChangeType, 
                    e.Name));

            // 監視開始
            watcher.EnableRaisingEvents = true;
            Console.ReadLine();
            watcher.Dispose();
            Console.WriteLine("-------------------------------");
        }
    }

    static class FileSystemWatcherExtensions
    {
        // ChangedイベントをIObservable<TEventArgs>にするヘルパーメソッド
        public static IObservable<FileSystemEventArgs> ChangedAsObservable(this FileSystemWatcher self)
        {
            return Observable.FromEvent<FileSystemEventHandler, FileSystemEventArgs>(
                h => (_, e) => h(e),
                h => self.Changed += h,
                h => self.Changed -= h);
        }
    }
}
